package com.hunan.api.catv.service.biz.like;

import com.google.gson.JsonObject;
import com.hunan.api.catv.common.CacheKey;
import com.hunan.api.catv.common.CacheName;
import com.hunan.api.catv.common.Constants;
import com.hunan.api.catv.entity.ServiceResult;
import com.hunan.api.catv.entity.enums.ColumnEnum;
import com.hunan.api.catv.entity.po.MemberLike;
import com.hunan.api.catv.entity.vo.MemberLikeVo;
import com.hunan.api.catv.entity.vo.NewsVo;
import com.hunan.api.catv.mq.MqConstants;
import com.hunan.api.catv.service.ResultService;
import com.hunan.api.catv.service.biz.mq.MqBiz;
import com.hunan.api.catv.service.biz.news.NewsBiz;
import com.hunan.api.catv.service.impl.like.MemberLikeService;
import com.hunan.api.catv.utils.GsonUtils;
import com.hunan.api.catv.utils.RedisUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.text.MessageFormat;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

@Service
public class MemberLikeBiz extends ResultService {

    @Autowired
    MemberLikeService memberLikeService;

    @Autowired
    MemberLikeBiz memberLikeBiz;

    @Autowired
    RedisUtils redisUtils;

    @Autowired
    MqBiz mqBiz;

    @Autowired
    NewsBiz newsBiz;

    public ServiceResult like(Integer collectType, Integer type, Integer itemId, Integer memberId) {
        JsonObject like = new JsonObject();
        like.addProperty("collectType", collectType);
        like.addProperty("itemId", itemId);
        like.addProperty("memberId", memberId);
        like.addProperty("type", type);
        mqBiz.push(MqConstants.like_exchange, MqConstants.like_routingkey, GsonUtils.toJson(like));
        if (type == 6) {
            return buildOK(true, collectType == 1 ? "投票成功" : "取消投票成功");
        }
        return buildOK(true, "");
    }

    public ServiceResult itemLike(Integer type, Integer itemId, Integer memberId) {
        JsonObject itemCollect = new JsonObject();
        //是否点赞
        String key = MessageFormat.format(CacheKey.likeHash, type);
        String likeHKey = MessageFormat.format(CacheKey.likeHKey, itemId, memberId);
        Boolean collect = (Boolean) redisUtils.hget(key, likeHKey);

        if (ObjectUtils.isEmpty(collect)) {
            MemberLike memberLike = new MemberLike();
            memberLike.setMemberId(memberId);
            memberLike.setItemId(itemId);
            memberLike.setType(type);
            MemberLikeVo memberLikeVo = memberLikeService.getById(memberLike);
            if (ObjectUtils.isEmpty(memberLikeVo)) {
                itemCollect.addProperty("like", Constants.disable);
            } else {
                itemCollect.addProperty("like", Constants.enable);
                redisUtils.hset(key, likeHKey, Constants.enable);
            }
        } else {
            itemCollect.addProperty("like", collect);
        }
        //点赞数
        String hKey = MessageFormat.format(CacheKey.likeCountHKey, type, itemId);
        Integer count = (Integer) redisUtils.hget(CacheKey.likeCount, hKey);
        if (ObjectUtils.isEmpty(count)) {
            MemberLike memberLike = new MemberLike();
            memberLike.setItemId(itemId);
            memberLike.setType(type);
            Integer sum = memberLikeService.count(memberLike);
            if (ObjectUtils.isEmpty(sum)) {
                itemCollect.addProperty("count", 0);
            } else {
                itemCollect.addProperty("count", sum);
                redisUtils.hset(CacheKey.likeCount, hKey, sum);
            }
        } else {
            itemCollect.addProperty("count", count);
        }

        return buildOK(itemCollect, "");
    }


    /**
     * 查询用户是否点赞
     * likeState  0:未点赞  1:点赞
     */
    public int itemLikeV2(Integer type, Integer itemId, Integer memberId) {
        int likeState = 1;
        //是否点赞
        String key = MessageFormat.format(CacheKey.likeHash, type);
        String likeHKey = MessageFormat.format(CacheKey.likeHKey, itemId, memberId);
        Boolean collect = (Boolean) redisUtils.hget(key, likeHKey);
        if (ObjectUtils.isEmpty(collect)) {
            MemberLike memberLike = new MemberLike();
            memberLike.setMemberId(memberId);
            memberLike.setItemId(itemId);
            memberLike.setType(type);
            MemberLikeVo memberLikeVo = memberLikeService.getById(memberLike);
            if (ObjectUtils.isEmpty(memberLikeVo)) {
                likeState = 0;
            } else {
                redisUtils.hset(key, likeHKey, Constants.enable);
            }
        } else {
            likeState = collect ? 1 : 0;
        }
        return likeState;
    }

    public void add(Integer type, Integer itemId, Integer memberId) {
        String key = MessageFormat.format(CacheKey.likeHash, type);
        String likeHKey = MessageFormat.format(CacheKey.likeHKey, itemId, memberId);
        //操作缓存
        redisUtils.hset(key, likeHKey, Constants.enable);

        String hKey = MessageFormat.format(CacheKey.likeCountHKey, type, itemId);
        //数量加1
        redisUtils.hincr(CacheKey.likeCount, hKey, 1);
        //数据持久化
        MemberLike memberLike = new MemberLike();
        memberLike.setMemberId(memberId);
        memberLike.setItemId(itemId);
        memberLike.setType(type);
        ServiceResult addResult = memberLikeService.add(memberLike);
        if (addResult.getStatus() && type.equals(ColumnEnum.news.getCode())) {
            newsBiz.incrCount(itemId, 1);
            NewsVo newsInfo = newsBiz.getNewsInfo(itemId);
            newsInfo.setLikeNum(newsInfo.getLikeNum() + 1);
            redisUtils.set(MessageFormat.format(CacheName.getNewsInfo, String.valueOf(itemId)), newsInfo);
        }
    }

    public void cancel(Integer type, Integer itemId, Integer memberId) {
        String key = MessageFormat.format(CacheKey.likeHash, type);
        String likeHKey = MessageFormat.format(CacheKey.likeHKey, itemId, memberId);
        //操作缓存
        redisUtils.hset(key, likeHKey, Constants.disable);
        String hKey = MessageFormat.format(CacheKey.likeCountHKey, type, itemId);

        //数据持久化
        MemberLike memberLike = new MemberLike();
        memberLike.setMemberId(memberId);
        memberLike.setItemId(itemId);
        memberLike.setType(type);
        ServiceResult delResult = memberLikeService.delete(memberLike);
        if (delResult.getStatus() && delResult.getData().equals(1) && type.equals(ColumnEnum.news.getCode())) {
            //数量减1
            redisUtils.hdecr(CacheKey.likeCount, hKey, 1);
            newsBiz.decrCount(itemId, 1);
            NewsVo newsInfo = newsBiz.getNewsInfo(itemId);
            newsInfo.setLikeNum(Math.max(newsInfo.getLikeNum() - 1, 0));
            redisUtils.set(MessageFormat.format(CacheName.getNewsInfo, String.valueOf(itemId)), newsInfo);
        }
    }

    public MemberLikeVo info(Integer memberId, Integer itemId, Integer type) {
        MemberLike memberLike = new MemberLike();
        memberLike.setMemberId(memberId);
        memberLike.setItemId(itemId);
        memberLike.setType(type);
        MemberLikeVo memberLikeVo = memberLikeService.getById(memberLike);
        if (!ObjectUtils.isEmpty(memberLikeVo)) {
            String key = MessageFormat.format(CacheKey.likeHash, type);
            String likeHKey = MessageFormat.format(CacheKey.likeHKey, itemId, memberId);
            redisUtils.hset(key, likeHKey, Constants.enable);
        }
        return memberLikeVo;
    }

    public List<Map<Object, Object>> queryAll(Integer type, Integer memberId) {
        Set<Object> set = new HashSet<Object>();
        String key = MessageFormat.format(CacheKey.likeHash, type);
        Map<Object, Object> map = redisUtils.hmget(key);
        if (!ObjectUtils.isEmpty(map)) {
            Set<Object> keySet = map.keySet();
            keySet.forEach(s -> {
                String hKey = s.toString();
                String m = hKey.substring(hKey.indexOf("-") + 1);
                if (m.equals(String.valueOf(memberId)) && Boolean.valueOf(map.get(hKey).toString()) == true) {
                    set.add(hKey.substring(0, hKey.indexOf("-")));
                }
            });
        }
        if (ObjectUtils.isEmpty(set)) {
            MemberLike memberLike = new MemberLike();
            memberLike.setMemberId(memberId);
            memberLike.setType(type);
            List<MemberLikeVo> list = memberLikeService.list(memberLike);
            if (!ObjectUtils.isEmpty(list)) {
                list.forEach(l -> {
                    set.add(l.getItemId());
                });
            }
        }
        List<Map<Object, Object>> result = new LinkedList<Map<Object, Object>>();
        if (!ObjectUtils.isEmpty(set)) {
            set.forEach(s -> {
                Map<Object, Object> m = new ConcurrentHashMap<Object, Object>();
                Integer count = 0;
                Integer itemId = Integer.valueOf(s.toString());
                String hKey = MessageFormat.format(CacheKey.likeCountHKey, type, itemId);
                Object c = redisUtils.hget(CacheKey.likeCount, hKey);
                if (ObjectUtils.isEmpty(c)) {
                    MemberLike memberLike = new MemberLike();
                    memberLike.setItemId(itemId);
                    memberLike.setType(type);
                    Integer sum = memberLikeService.count(memberLike);
                    if (ObjectUtils.isEmpty(sum)) {
                        count = 0;
                    } else {
                        count = sum;
                        redisUtils.hset(CacheKey.likeCount, hKey, sum);
                    }
                } else {
                    count = Integer.valueOf(c.toString());
                }
                m.put("itemId", itemId);
                m.put("count", count);
                result.add(m);
            });
        }
        return result;
    }

}
